package com.acme.chat.stresstest;

import com.acme.chat.client.ChatClient;
import com.acme.chat.client.Client;
import com.acme.chat.message.ChatMessage;
import com.acme.chat.message.Message;
import com.acme.chat.message.MessageType;
import com.acme.chat.server.ServerImpl;
import com.acme.chat.server.TCPServer;

public class StressTest implements Runnable {

    private static final int NUMBER_OF_CLIENTS = 100;
    private static final String message998Len = "ООП возникло в результате развития идеологии процедурного программирования, где данные и подпрограммы (процедуры, функции) их обработки формально не связаны. Для дальнейшего развития объектно-ориентированного программирования часто большое значение имеют понятия события (так называемое событийно-ориентированное программирование) и компонента (компонентное программирование, КОП).Формирование КОП от ООП произошло, как случилось формирование модульного от процедурного программирования: процедуры сформировались в модули — независимые части кода до уровня сборки программы, так объекты сформировались в компоненты — независимые части кода до уровня выполнения программы. Взаимодействие объектов происходит посредством сообщений. Результатом дальнейшего развития ООП, по-видимому, будет агентно-ориентированое программирование, где агенты — независимые части кода на уровне выполнения. Взаимодействие агентов происходит посредством изменения среды, в которой они находятся. Языковые конструкции,";

    private static Client[] clients = new Client[NUMBER_OF_CLIENTS];
    private static Message message = new ChatMessage(MessageType.MESSAGE, message998Len);

    public static void main(String[] args) throws InterruptedException {
        String[] names = new String[NUMBER_OF_CLIENTS];
        String startName = "*User_";
        for (int i = 0; i < NUMBER_OF_CLIENTS; i++) {
            names[i] = startName + i;
        }

        String serverAddres = "localhost";
        int port = 1900;
        String room = "1";

        ServerImpl server = new ServerImpl();
        TCPServer tcpServer = new TCPServer(server, port);
        (new Thread(tcpServer)).start();

        for (int i = 0; i < NUMBER_OF_CLIENTS; i++) {
            clients[i] = new Client(serverAddres, port, room, names[i]);
            clients[i].start();
        }

        // wait while all connected to the server
        Thread.sleep(3000);

        // sendOneMessageTest();
        sendOneMessageEverySecondTest();

//        StressTest st = new StressTest();
//        st.start();
    }

    private static void sendOneMessageTest() {
        System.out.println(">>>>>> START one message Test");
        clients[0].sendMessage(message);
    }

    private static void sendOneMessageEverySecondTest() {
        System.out.println(">>>>>> START one message Test every second");

        new Thread() {
            @Override
            public void run() {
                while (true) {
                    System.out.println("New test");
                    long now = System.currentTimeMillis();

                    for (int i = 0; i < 100; i++) {
                        clients[i].sendMessage(message);
                    }
                    System.out.println("************** SLEEP *****************");
                    while (System.currentTimeMillis() - now < 1000) {
                        System.out.println("delta = " + (System.currentTimeMillis() - now));
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }.start();
    }

    private void start() {
        (new Thread(this)).start();
    }

    public void run() {
        while(true) {
            long current = System.currentTimeMillis();
            for (ChatClient client : clients) {
                client.sendMessage(message);
            }
            while ((System.currentTimeMillis() - current) < 1000) {
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
